package com.sky.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.context.BaseContext;
import com.sky.dto.CategoryDTO;
import com.sky.dto.CategoryPageQueryDTO;
import com.sky.entity.Category;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.mapper.CategoryMapper;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.result.PageResult;
import com.sky.service.CategoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 这个类 CategoryServiceImpl  是分类服务接口 CategoryService 的实现类，负责处理分类相关的业务逻辑
 */
@Service
@Slf4j
public class CategoryServiceImpl implements CategoryService {

    // //这是一个标准的Spring依赖注入配置，用于将MyBatis的CateMapper接口注入到Service层
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private DishMapper dishMapper;
    @Autowired
    private SetmealMapper setmealMapper;

    /**
     * 新增分类
     * @param categoryDTO
     * 调用持久层mapper,把数据插进去，传给持久层还是建议使用实体类，所以这里要做一个对象的转换，DTO转换为实体
     */
    public void save(CategoryDTO categoryDTO){
        Category category = new Category();
        //categoryDTO和category的属性都能对应上，所以不需要一个个set,使用对象属性拷贝
        BeanUtils.copyProperties(categoryDTO,category);
        //category里面的属性更多，所以后面几个属性需要手动去设置
        //设置分类状态，默认正常状态，1表示正常，0表示锁定,定义了一个常量类,方便后期维护
        category.setStatus(StatusConstant.DISABLE);

        //设置当前记录的创建时间和修改时间
//        category.setCreateTime(LocalDateTime.now());
//        category.setUpdateTime(LocalDateTime.now());

        //设置当前记录的创建人和修改人id,从线程空间中取出用户id
//        category.setCreateUser(BaseContext.getCurrentId());
//        category.setUpdateUser(BaseContext.getCurrentId());

        //调用持久层把数据插入
        categoryMapper.insert(category);
    }

    /**
     * 分页查询
     * @param categoryPageQueryDTO
     * @return
     */
    @Override
    public PageResult pageQuery(CategoryPageQueryDTO categoryPageQueryDTO) {
        //开始分页查询
        PageHelper.startPage(categoryPageQueryDTO.getPage(),categoryPageQueryDTO.getPageSize());
        //调用Mapper的查询方法，此时PageHelper会自动拦截这个查询并进行分页处理
        Page<Category> page = categoryMapper.pageQuery(categoryPageQueryDTO);
        //对Page对象进行加工处理
        long total = page.getTotal();
        List<Category> records = page.getResult();
        //获得这两个值后，把它们封装到PageResult里面
        return new PageResult(total,records);
    }

    /**
     * 启用，禁用分类
     * @param status
     * @param id
     */
    @Override
    public void startOrStop(Integer status, Long id) {
        //update category set status = ? where id ?
        //把update语句写成动态的，根据传进来参数的不同，可以修改多个字段，通用性更强
//        Category category = new Category();
//        category.setStatus(status);
//        category.setId(id);
//        以上是传统构造实体对象方法，实体类category有@Builder构建器注解，则可用以下方法
        Category category = Category.builder()
                .status(status)
//                .updateTime(LocalDateTime.now())
//                .updateUser(BaseContext.getCurrentId())
                .id(id)
                .build();

        categoryMapper.update(category);


    }


    /**
     * 根据类型查询分类
     * @param type
     * @return
     */

    public List<Category> list(Integer type) {
        return categoryMapper.list(type);
    }

    /**
     * 修改分类
     * @param categoryDTO
     */
    @Override
    public void update(CategoryDTO categoryDTO) {
        Category category = new Category();
        BeanUtils.copyProperties(categoryDTO,category);

        category.setStatus(StatusConstant.DISABLE);
//        category.setUpdateTime(LocalDateTime.now());
//        category.setUpdateUser(BaseContext.getCurrentId());

        categoryMapper.update(category);
    }


    /**
     * 根据id删除分类
     * @param id
     */
    @Override
    public void deleteById(Long id) {
    //查询当前分类是否关联了菜品，如果关联了就抛出业务异常
        Integer count = dishMapper.countByCategoryId(id);
        if (count > 0){
            //当前分类下有菜品，不能删除
            throw new DeletionNotAllowedException(MessageConstant.CATEGORY_BE_RELATED_BY_DISH);
        }
        //查询当前分类是否关联了套餐，如果关联了就抛出业务异常
        setmealMapper.countByCategoryId(id);
        if (count > 0){
            //当前分类下有套餐，不能删除
            throw new DeletionNotAllowedException(MessageConstant.CATEGORY_BE_RELATED_BY_SETMEAL);
        }
        //删除分类数据
        categoryMapper.deleteById(id);
    }
}
